package com.lihonghao.gateway;

import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ClassUtil;
import com.lihonghao.DefaultApplication;
import com.lihonghao.consts.HTTP;
import com.lihonghao.gateway.bean.ModelContainer;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class DefaultGate {
    public static ModelContainer modelContainer = null;
    public static Set<String> mapSet = Collections.synchronizedSet(new HashSet<>());
    public static Map<String, GateDefinition> mapWay = Collections.synchronizedMap(new ConcurrentHashMap<>());


    public static void init() {
        String classPath = ClassUtil.getPackage(DefaultApplication.class);
        Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation(classPath, ControllerNetty.class);
        modelContainer = new ModelContainer(classes);
        for (Class<?> clazz : classes) {
            String className = ClassUtil.getClassName(clazz, true);
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                Router router = method.getAnnotation(Router.class);
                if (router != null) {
                    // 获取Router注解中的路径，作为路由的标识
                    String path = router.path();
                    String methodType = router.method();
                    mapSet.add(StrBuilder.create().append(methodType).append(":").append(path).toString());
                    mapWay.put(StrBuilder.create().append(methodType).append(":").append(path).toString(), new GateDefinition().setClazz(clazz).setClassName(className).setMethod(method));
                }
            }
        }
    }

    public static class action {
        public static Object of(String path) {
            return of(path, HTTP.Method.GET, null);
        }

        public static Object of(String path, String method) {
            return of(path, method, null);
        }

        public static Object of(String path, String method, HashMap<String, String> resMap) {
            if (modelContainer == null) {
                synchronized (DefaultGate.class) {
                    if (modelContainer == null) {
                        init();
                    }
                }
            }
            String key = StrBuilder.create().append(method).append(":").append(path).toString();
            if (mapSet.contains(key)) {
                GateDefinition gateDefinition = mapWay.get(key);
                Object bean = modelContainer.getBean(gateDefinition.getClassName());
                if (bean != null) {
                    Object result = null;
                    Method methodModel = gateDefinition.getMethod();
                    try {
                        if (resMap != null && !resMap.isEmpty()) {
                            result = methodModel.invoke(bean, resMap);
                        } else {
                            result = methodModel.invoke(bean);
                        }
                        return result;
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                        return "error";
                    } catch (Throwable e) {
                        e.printStackTrace();
                        return "error";
                    }
                }
            }
            return "null";
        }
    }
}
